﻿// ***************************************************************
//  version:  0.4.0   date: 12/12/2007-2008
//  -------------------------------------------------------------
//  
//  -------------------------------------------------------------
//  (C)2007-2008 Midapex All Rights Reserved
// ***************************************************************
// 
// ***************************************************************
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SQLite;
using System.Data.Common;
using System.Data;

namespace Midapex.SmartOrm.Provider
{
    /// <summary>
    /// 支持SQLite数据库，不能用于多线程同时读写的环境。
    /// </summary>
    class SQLiteSession:OrmSession
    {
        public SQLiteSession(string conn)
        {
            this.dbConnString = conn;
        }

        public override System.Data.Common.DbConnection CreateDbConnection()
        {
            /*
            DbProviderFactory factory = SQLiteFactory.Instance;
            DbConnection conn = factory.CreateConnection();
            conn.ConnectionString = dbConnString;
            return conn;
             */
            return new SQLiteConnection(dbConnString);
        }

        public override string QuoteParam(string name)
        {
            return PREFIX;
        }

        public override string PREFIX
        {
            get
            {
                return "?";
            }
        }

        protected override string LastInsertedIdentityStatement(Table table)
        {
            string sql = string.Format("SELECT MAX({1}) FROM {0}", QuoteName(table.Name), QuoteName(table.PrimaryColumn.Name));
            return sql;
        }

        protected override string ColumnStatement(Column col)
        {
            StringBuilder sql = new StringBuilder(32);
            sql.Append("\t");
            sql.Append(QuoteName(col.Name));
            sql.Append("\t\t");

            switch (col.DbType)
            {
                case DbType.String:
                    {
                        if (col.Size > 4000)
                        {
                            sql.Append("TEXT");
                        }
                        else
                        {
                            sql.Append(string.Format("VARCHAR({0})", col.Size));
                        }

                        break;
                    }
                case DbType.Int32:
                    {
                        sql.Append("INTEGER");
                        
                        break;
                    }
                case DbType.Boolean:
                    {
                        sql.Append("BIT");
                        break;
                    }
                case DbType.Binary:
                    {
                        sql.Append("IMAGE");
                        break;
                    }
                case DbType.Byte:
                    {
                        sql.Append("INTEGER");
                        break;
                    }
                case DbType.Int16:
                    {
                        sql.Append("INTEGER");
                        break;
                    }
                case DbType.Single:
                    {
                        sql.Append("FLOAT");
                        break;
                    }
                case DbType.Double:
                    {
                        sql.Append("REAL");
                        break;
                    }
                case DbType.DateTime:
                    {
                        sql.Append("DATETIME");
                        break;
                    }
                case DbType.Int64:
                    {
                        sql.Append("INTEGER");
                        break;
                    }
                default:
                    {
                        sql.Append(string.Format("VARCHAR({0})", col.Size));
                        break;
                    }
            }

           if(col.IsPrimaryKey)
            {
                sql.Append("\tPRIMARY KEY");
            }
            if(col.Identity)
            {
                sql.Append("\tAUTOINCREMENT");
            }

            if (!col.AllowNullValue)
                sql.Append("\tNOT NULL ");
            if (col.Unique)
                sql.Append("\tUNIQUE ");

            return sql.ToString();
        }

        public override bool IsTableExist(Table table)
        {
            string sql = string.Format("SELECT COUNT(*) FROM sqlite_master WHERE name='{0}' and type = 'table'", table.Name);
            int count = int.Parse(ExecuteScalar(sql).ToString());
            return count == 1 ? true : false;
        }

        public override System.Data.Common.DbCommand CreateDbCommand(string sql)
        {
            return new SQLiteCommand();
        }

        protected override void CreateSelectCommand(Query query, Table table)
        {
            DbCommand cmd = DbCmd;
            cmd.Parameters.Clear();

            StringBuilder sql = new StringBuilder(300);
            sql.Append("SELECT ");

            sql.Append(" * FROM ");
            sql.Append(QuoteName(table.Name));
            sql.Append(" WHERE 1=1"); //防止SQL攻击

            if (query != null)
            {
                //添加范围条件
                if (!string.IsNullOrEmpty(query.Where))
                {
                    sql.Append(" AND (");
                    sql.Append(query.Where);
                    sql.Append(")");
                    foreach (QueryParam param in query.Params)
                    {
                        cmd.Parameters.Add(MakeParam(table, param));
                    }
                }

                if (query.Orders.Count != 0)
                {
                    OrderCommand(query, table, sql);
                }

                if (query != null && query.SelectRows > 0)
                {
                    sql.Append(" LIMIT ");
                    sql.Append(query.SelectRows);
                }

            }

            cmd.CommandText = sql.ToString();

        }
    }
}
